﻿/*
 * stringref.hpp
 *
 *  Created on: 2016年12月12日
 *      Author: work
 */

#ifndef _DM_STRING_STRINGREF_HPP_
#define _DM_STRING_STRINGREF_HPP_

#include <dm/export.hpp>

#ifndef DM_API_STRING
#define DM_API_STRING DM_API_IMPORT
#endif

#include <dm/types.hpp>
#include <cstdio>

namespace dm{
namespace string{

class DM_API_STRING CStringRef{
public:
	CStringRef( const char* str ):m_r(str){}

	inline bool operator==( const char* str )const{
		return *this==CStringRef(str);
	}

	bool operator==( const CStringRef& str )const;
	inline bool operator!=( const char* str )const{
		return *this != CStringRef(str);
	}

	inline bool operator!=( const CStringRef& str )const{
		return !(*this==str);
	}

	/**
	 * 按字典顺序比较。字典顺序由ASCII编码确定
	 * @param str
	 * @return
	 */
	bool operator>( const CStringRef& str )const;
	bool operator>=( const CStringRef& str )const;

	inline bool operator<( const CStringRef& str )const{
		return str>(*this);
	}

	inline bool operator<=( const CStringRef& str )const{
		return str>=(*this);
	}

	int len()const;

	dm::uint8 toUint8( bool* ok=0 )const;
	dm::int8 toInt8(  bool* ok=0 )const;
	dm::uint16 toUint16(  bool* ok=0 )const;
	dm::int16 toInt16( bool* ok=0 )const;
	dm::uint32 toUint32( bool* ok=0 )const;
	dm::int32 toInt32( bool* ok=0 )const;
	dm::uint64 toUint64( bool* ok=0 )const;
	dm::int64 toInt64( bool* ok=0 )const;

	dm::float32 toFloat32( bool* ok=0 )const;
	dm::float64 toFloat64( bool* ok=0 )const;

	dm::uint8 getHex( int pos )const;

	/* getHexValue_xx系类函数为右侧为低位的十六进制数
	 * 允许高位截断，高位补零
	 */
	inline dm::uint8 getHexValue_uint8()const{
		return getHexValue<dm::uint8,2>();
	}

	inline dm::uint16 getHexValue_uint16()const{
		return getHexValue<dm::uint16,4>();
	}

	inline dm::uint32 getHexValue_uint32()const{
		return getHexValue<dm::uint32,8>();
	}

	inline dm::uint64 getHexValue_uint64()const{
		return getHexValue<dm::uint64,16>();
	}

	inline int getHexes( dm::uint8* buf,const int& size )const{
		return getHexes(len(),buf,size);
	}


	/**
	 * 如果是十六进制数，则转换成数值，并保存到字节数组。
	 * @param len 转换的字符串长度
	 * @param buf 保存的字节数组
	 * @param size buf长度
	 * @return buf中有效数据个数
	 */
	int getHexes( const int& len,dm::uint8* buf,const int& size )const;

	// 格式化数据读取
	template<typename T>
	inline bool getFormated( const char* fmt,T& v )const{
		if( len()<=0 )
			return false;
		return 1==std::sscanf(m_r,fmt,&v);
	}

	inline const char* c_str()const{
		return m_r;
	}

	void dump( char* buf )const;
	bool dump( char* buf,int size )const;
	bool dump( char* buf,int size,int start )const;
	bool dump( char* buf,int size,int start,int num )const;

	bool dumpSome( char* buf,int maxNum )const;

	bool dumpAutoMalloc( char* *pBuf )const;

	inline bool isStartWith( const char* str )const{
		return isStartWith(str,CStringRef(str).len() );
	}

	bool isStartWith( const char* str,int num )const;

	inline bool isEndWith( const char* str )const{
		return isEndWith(str,CStringRef(str).len());
	}

	bool isEndWith( const char* str,int num )const;

	int nextChar( const char& c,int skip=0 )const;
	int nextNoneChar( const char& c,int skip=0 )const;
	int nextChars( const char* cs,int skip=0 )const;
	int nextNoneChars( const char* cs,int skip=0 )const;
	int nextChars( const char& cstart,const char& cend,int skip=0 )const;
	int nextNoneChars( const char& cstart,const char& cend,int skip=0 )const;

	int lastChar( const char& c,int skip=0 )const;
	int lastNoneChar( const char& c,int skip=0 )const;
	int lastChars( const char* cs,int skip=0 )const;
	int lastNoneChars( const char* cs,int skip=0 )const;
	int lastChars( const char& cstart,const char& cend,int skip=0 )const;
	int lastNoneChars( const char& cstart,const char& cend,int skip=0 )const;

	int nextSub( const char* str,int skip=0 )const;
	int lastSub( const char* str,int skip=0 )const;

	bool isNum()const;
	bool isHex()const;
	bool isAlaphas()const;

protected:
	template<typename T,int TSize>
	T getHexValue()const{
		if( !isHex() )
			return 0;
		int l = len();
		int p = l - TSize;
		T rt = getHex(p);
		++p;
		while( p<l ){
			rt <<= 4;
			rt |= getHex(p);
			++p;
		}

		return rt;
	}

protected:
	const char* m_r;
};

}
}

#endif /* INCLUDE_DM_STRING_STRINGREF_HPP_ */
